package com.hgl.bi.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hgl.bi.common.annotation.RequirePmt;
import com.hgl.bi.common.constant.ErrorCode;
import com.hgl.bi.common.constant.ProgressStatus;
import com.hgl.bi.common.manager.RedisManager;
import com.hgl.bi.common.model.vo.R;
import com.hgl.bi.common.utils.AssertUtil;
import com.hgl.bi.web.config.DeepSeekClient;
import com.hgl.bi.web.config.RabbitConfig;
import com.hgl.bi.web.entity.AnalyzeEntity;
import com.hgl.bi.web.entity.CleanEntity;
import com.hgl.bi.web.model.dto.*;
import com.hgl.bi.web.service.AnalyzeService;
import com.hgl.bi.web.service.CleanService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @program: BI
 * @description: AI任务执行控制层
 * @author: hgl
 * @create: 2025-02-10 10:37
 */
@Tag(name = "数据处理模块")
@RestController
public class DataController {

    @Autowired
    private CleanService cleanService;

    @Autowired
    private AnalyzeService analyzeService;

    @Autowired
    private DeepSeekClient deepSeekClient;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisManager redisManager;

    /**
     * 分页查询数据分析记录列表
     *
     * @param id 数据集ID
     * @return 数据分析记录列表
     */
    @Operation(summary = "查询数据分析记录列表", tags = "数据处理模块")
    @GetMapping("/data/analyze/list/{id}")
    public R<List<AnalyzeEntity>> getAnalysisList(@RequestHeader("satoken") String satoken,
                                                  @PathVariable String id) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        QueryWrapper<AnalyzeEntity> wrapper = new QueryWrapper<AnalyzeEntity>()
                .eq("set_id", id)
                .eq("user_id", userId)
                .orderByDesc("start_time");
        List<AnalyzeEntity> list = analyzeService.list(wrapper);
        return R.success(list);
    }

    /**
     * 统计数据分析数量
     *
     * @return 数据分析数量
     */
    @Operation(summary = "统计数据分析数量", tags = "数据处理模块")
    @GetMapping("/data/analyze/sum")
    public R<Long> countAnalyze() {
        long count = analyzeService.count();
        return R.success(count);
    }

    /**
     * 统计数据清洗数量
     *
     * @return 数据清洗数量
     */
    @Operation(summary = "统计数据清洗数量", tags = "数据处理模块")
    @GetMapping("/data/clean/sum")
    public R<Long> countClean() {
        long count = cleanService.count();
        return R.success(count);
    }

    /**
     * 数据清洗
     *
     * @param id 文件ID
     * @return R<String>
     * @author hgl
     */
    @RequirePmt(code = "data:clean")
    @Transactional
    @Operation(summary = "数据清洗", tags = "数据处理模块")
    @PostMapping("/data/clean/{id}")
    public R<Long> dataClean(@RequestHeader("satoken") String satoken,
                             @PathVariable Long id) {
        // 非空校验
        AssertUtil.notNull(id, ErrorCode.REQUEST_PARAM_ERROR);
        // 更新状态为待执行
        CleanEntity clean = new CleanEntity();
        // 获取当前登录用户id
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        clean.setUserId(userId);
        clean.setFileId(id);
        clean.setProgress(ProgressStatus.WAITING.getCode());
        clean.setAiModel(deepSeekClient.getModel());
        cleanService.save(clean);
        // 发送数据清洗消息（使用事务同步）
        rabbitTemplate.convertAndSend(
                RabbitConfig.DATA_CLEAN_EXCHANGE,
                RabbitConfig.DATA_CLEAN_ROUTING_KEY,
                new CleanMsgDto(clean.getId(), id),
                message -> {
                    // 设置消息持久化
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    return message;
                }
        );
        return R.success(clean.getId());
    }

    /**
     * 获取数据清洗结果
     *
     * @param id 任务ID
     * @return R<CleanEntity>
     * @author hgl
     */
    @Operation(summary = "获取数据清洗结果", tags = "数据处理模块")
    @GetMapping("/data/clean/get/{id}")
    public R<CleanEntity> getClean(@PathVariable String id) {
        CleanEntity entity = cleanService.lambdaQuery()
                .eq(CleanEntity::getId, id)
                .one();
        return R.success(entity);
    }

    /**
     * 数据分析
     *
     * @param analyzeDto 分析需求
     * @return R<String>
     * @author hgl
     */
    @RequirePmt(code = "data:analyze")
    @Transactional
    @Operation(summary = "数据分析", tags = "数据处理模块")
    @PostMapping("/data/analyze")
    public R<Long> dataAnalyze(@RequestHeader("satoken") String satoken, @RequestBody AnalDto analyzeDto) {
        Long setId = analyzeDto.getSetId();
        String demand = analyzeDto.getDemand();
        // 非空校验
        AssertUtil.notNull(analyzeDto, ErrorCode.REQUEST_PARAM_ERROR);
        AssertUtil.notNull(setId, ErrorCode.SET_ID_NULL);
        AssertUtil.notEmpty(demand, ErrorCode.DEMAND_NOT_NULL);

        // 更新状态为待执行
        AnalyzeEntity analyze = new AnalyzeEntity();
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        analyze.setSetId(setId);
        analyze.setUserId(userId);
        analyze.setDemand(demand);
        analyze.setProgress(ProgressStatus.WAITING.getCode());
        analyze.setAiModel(deepSeekClient.getModel());
        analyzeService.save(analyze);
        // 发送数据清洗消息（使用事务同步）
        rabbitTemplate.convertAndSend(
                RabbitConfig.DATA_ANALYZE_EXCHANGE,
                RabbitConfig.DATA_ANALYZE_ROUTING_KEY,
                new AnalMsgDto(analyze.getId(), setId, demand),
                message -> {
                    // 设置消息持久化
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    return message;
                }
        );
        return R.success(analyze.getId());
    }

    /**
     * 获取数据分析结果
     *
     * @param id 任务ID
     * @return R<AnalyzeEntity>
     * @author hgl
     */
    @Operation(summary = "获取数据分析结果", tags = "数据处理模块")
    @GetMapping("/data/analyze/get/{id}")
    public R<AnalyzeEntity> getAnalyze(@PathVariable String id) {
        AnalyzeEntity entity = analyzeService.lambdaQuery()
                .eq(AnalyzeEntity::getId, id)
                .one();
        return R.success(entity);
    }

    /**
     * 分页查询清洗后数据列表
     *
     * @param pageDto 分页信息
     * @return 清洗后数据列表
     * @author hgl
     */
    @Operation(summary = "查询清洗后数据列表", tags = "数据处理模块")
    @GetMapping("/data/clean/list")
    public R<Page<CleanEntity>> listCleanDatas(@RequestHeader("satoken") String satoken, @ParameterObject CleanPageDto pageDto) {
        // 非空校验
        AssertUtil.notNull(pageDto, ErrorCode.REQUEST_PARAM_ERROR);
        // 分页查询
        Page<CleanEntity> page = new Page<>(pageDto.getPage(), pageDto.getSize());
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        QueryWrapper<CleanEntity> wrapper = new QueryWrapper<CleanEntity>()
                .eq("user_id", userId);
        if (pageDto.getFileId() != null) wrapper
                .eq("file_id", pageDto.getFileId());
        if (pageDto.getProgress() != null) wrapper
                .eq("progress", pageDto.getProgress());
        wrapper.orderByDesc("start_time");
        Page<CleanEntity> cleanPage = cleanService.page(page, wrapper);
        return R.success(cleanPage);
    }

    /**
     * 分页查询分析后数据列表
     *
     * @param pageDto 分页信息
     * @return 分析后数据列表
     * @author hgl
     */
    @Operation(summary = "查询分析后数据列表", tags = "数据处理模块")
    @GetMapping("/data/analyze/list")
    public R<Page<AnalyzeEntity>> listAnalyzeDatas(@RequestHeader("satoken") String satoken, @ParameterObject AnalPageDto pageDto) {
        // 非空校验
        AssertUtil.notNull(pageDto, ErrorCode.REQUEST_PARAM_ERROR);
        // 分页查询
        Page<AnalyzeEntity> page = new Page<>(pageDto.getPage(), pageDto.getSize());
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        long userId = userInfo.getId();
        QueryWrapper<AnalyzeEntity> wrapper = new QueryWrapper<AnalyzeEntity>()
                .eq("user_id", userId);
        if (pageDto.getSetId() != null) wrapper
                .eq("set_id", pageDto.getSetId());
        if (pageDto.getProgress() != null) wrapper
                .eq("progress", pageDto.getProgress());
        wrapper.orderByDesc("start_time");
        Page<AnalyzeEntity> cleanPage = analyzeService.page(page, wrapper);
        return R.success(cleanPage);
    }
}
